lexer grammar PLCSTLexer;

//Identifiers
fragment Letter : [A-Z_];
fragment Digit : [0-9];
fragment Bit : [01];
fragment Octal_Digit : [0-7];
fragment Hex_Digit : [0-9A-F];

//Numeric literal

Unsigned_Int : Digit ( Underline ? Digit )*;

Signed_Int : ( Plus | Minus )? Unsigned_Int;

Binary_Int : '2#' ( Underline ? Bit )+;

Octal_Int : '8#' ( Underline ? Octal_Digit )+;

Hex_Int : '16#' ( Underline ? Hex_Digit )+;

Science_real : Signed_Int Dot Unsigned_Int ( 'E' Signed_Int )?;

Const_bool : 'FALSE' | 'TRUE';

//Character String literal &  Two-character combinations in character strings
fragment S_Byte_Char_Value : Common_Char_Value | '$\'' | '"' | ('$' Hex_Digit Hex_Digit);

fragment D_Byte_Char_Value : Common_Char_Value | '\'' | '$"' | ('$' Hex_Digit Hex_Digit Hex_Digit Hex_Digit);

fragment Common_Char_Value : ~ ['\\\r\n] | '$$' | '$L' | '$N' | '$P' | '$R' | '$T';

S_Byte_Char_Str : '\'' S_Byte_Char_Value + '\'';

D_Byte_Char_Str : '"' D_Byte_Char_Value + '"';

//Duration literals &  Date and time of day literals
Duration : ( Time_Type_Name | 'T' | 'LT' ) TypeSign ( Plus | Minus )? Interval;

fragment Fix_Point : Unsigned_Int ( Dot Unsigned_Int )?;

Interval : Days | Hours | Minutes | Seconds | Milliseconds | Microseconds | Nanoseconds;

Days : ( Fix_Point 'd' ) | ( Unsigned_Int 'd' Underline ? ) Hours ?;

Hours : ( Fix_Point 'h' ) | ( Unsigned_Int 'h' Underline ? ) Minutes ?;

Minutes : ( Fix_Point 'm' ) | ( Unsigned_Int 'm' Underline ? ) Seconds ?;

Seconds : ( Fix_Point 's' ) | ( Unsigned_Int 's' Underline ? ) Milliseconds ?;

Milliseconds : ( Fix_Point 'ms' ) | ( Unsigned_Int 'ms' Underline ? ) Microseconds ?;

Microseconds : ( Fix_Point 'us' ) | ( Unsigned_Int 'us' Underline ? ) Nanoseconds ?;

Nanoseconds : Fix_Point 'ns';

Time_Of_Day : ( Tod_Type_Name | 'LTIME_OF_DAY' ) TypeSign Daytime;

Daytime : Day_Hour ':' Day_Minute ':' Day_Second;

Day_Hour : Unsigned_Int;

Day_Minute : Unsigned_Int;

Day_Second : Fix_Point;

Date : ( Date_Type_Name | 'D' | 'LD' ) TypeSign Date_Literal;

Date_Literal : Year Minus Month Minus Day;

Year : Unsigned_Int;

Month : Unsigned_Int;

Day : Unsigned_Int;

Date_And_Time : ( DT_Type_Name | 'LDATE_AND_TIME' ) TypeSign Date_Literal Minus Daytime;

// Elementary data types

Int_Type_Name : Sign_Int_Type_Name | Unsign_Int_Type_Name;

fragment Sign_Int_Type_Name : 'SINT' | 'INT' | 'DINT' | 'LINT';

fragment Unsign_Int_Type_Name : 'USINT' | 'UINT' | 'UDINT' | 'ULINT';

Real_Type_Name : 'REAL' | 'LREAL';

CHAR : 'CHAR';

WCHAR : 'WCHAR';

SString_Type_Name : STRING ( '[' Unsigned_Int ']' )?;

WString_Type_Name : WSTRING ( '[' Unsigned_Int ']' )?;

Time_Type_Name : 'TIME' | 'LTIME';

Date_Type_Name : 'DATE' | 'LDATE';

fragment Tod_Type_Name : 'TIME_OF_DAY' | 'TOD' | 'LTOD';

fragment DT_Type_Name : 'DATE_AND_TIME' | 'DT' | 'LDT';

Bool_Type_Name : 'BOOL';

Multibits_Type_Name : 'BYTE' | 'WORD' | 'DWORD' | 'LWORD';

//Declaration of user-defined data types and initialization

TYPE : 'TYPE';

END_TYPE : 'END_TYPE';

ARRAY : 'ARRAY';

OF : 'OF';

STRUCT : 'STRUCT';

END_STRUCT : 'END_STRUCT';

OVERLAP : 'OVERLAP';

// Directly represented variables
Direct_Variable : '%' ( 'I' | 'Q' | 'M' ) ( 'X' | 'B' | 'W' | 'D' | 'L' )? Unsigned_Int ( Dot Unsigned_Int )*;

//Reference operations

REF_TO : 'REF_TO';

Null : 'NULL';
REF : 'REF';

//Declaration of variables/Table 14 – Initialization of variables

THIS : 'THIS';

VAR_INPUT : 'VAR_INPUT';

END_VAR : 'END_VAR';

RETAIN : 'RETAIN';

NON_RETAIN : 'NON_RETAIN';

R_EDGE : 'R_EDGE';

F_EDGE : 'F_EDGE';

VAR_OUTPUT : 'VAR_OUTPUT';

VAR_IN_OUT : 'VAR_IN_OUT';

VAR : 'VAR';

CONSTANT : 'CONSTANT';

VAR_TEMP : 'VAR_TEMP';

VAR_EXTERNAL : 'VAR_EXTERNAL';

VAR_GLOBAL : 'VAR_GLOBAL';

AT : 'AT';

STRING : 'STRING';

WSTRING : 'WSTRING';

Var_Location : '%' ( 'I' | 'Q' | 'M' ) '*';

// standard function names
TRUNC : 'TRUNC';
ABS : 'ABS';
SQRT : 'SQRT';
LN : 'LN';
LOG : 'LOG';
EXP : 'EXP';
SIN : 'SIN';
COS : 'COS';
TAN : 'TAN';
ASIN : 'ASIN';
ACOS : 'ACOS';
ATAN : 'ATAN';
ATAN2 : 'ATAN2';
ADD : 'ADD';
SUB : 'SUB';
MUL : 'MUL';
DIV : 'DIV';
EXPT : 'EXPT';
MOVE : 'MOVE';
SHL : 'SHL';
SHR : 'SHR';
ROL : 'ROL';
ROR : 'ROR';
SEL : 'SEL';
MAX : 'MAX';
MIN : 'MIN';
LIMIT : 'LIMIT';
MUX : 'MUX';
GT : 'GT';
GE : 'GE';
EQ : 'EQ';
LE : 'LE';
LT : 'LT';
NE : 'NE';
LEN : 'LEN';
LEFT : 'LEFT';
RIGHT : 'RIGHT';
MID : 'MID';
CONCAT : 'CONCAT';
INSERT : 'INSERT';
DELETE : 'DELETE';
REPLACE : 'REPLACE';
FIND : 'FIND';


FUNCTION : 'FUNCTION';

END_FUNCTION : 'END_FUNCTION';

//Function block type declaration & Function block instance declaration
Std_FB_Name : 'SR' | 'RS' | 'R_TRIG' | 'F_TRIG' | 'CTU'| 'CTD' | 'CTUD' | 'TP' | 'TON' | 'TOF';
 // incomplete list

FUNCTION_BLOCK : 'FUNCTION_BLOCK';

FINAL : 'FINAL';

ABSTRACT : 'ABSTRACT';

EXTENDS : 'EXTENDS';

IMPLEMENTS : 'IMPLEMENTS';

END_FUNCTION_BLOCK : 'END_FUNCTION_BLOCK';

METHOD : 'METHOD';

END_METHOD : 'END_METHOD';

OVERRIDE : 'OVERRIDE';

//Class &  Textual call of methods – Formal and non-formal parameter list
CLASS : 'CLASS';

END_CLASS : 'END_CLASS';

INTERFACE : 'INTERFACE';

END_INTERFACE : 'END_INTERFACE';

PUBLIC : 'PUBLIC';

PROTECTED : 'PROTECTED';

PRIVATE : 'PRIVATE';

//Program declaration
PROGRAM : 'PROGRAM';

END_PROGRAM : 'END_PROGRAM';

VAR_ACCESS : 'VAR_ACCESS';

//Sequential Function Chart (SFC)
INITIAL_STEP : 'INITIAL_STEP';

END_STEP : 'END_STEP';

STEP : 'STEP';

ACTION_QUALIFIER : 'N' | 'R' | 'S' | 'P';
ACTION_TIME_QUALIFIER :  'L' | 'D' | 'SD' | 'DS' | 'SL' ;

TRANSITION : 'TRANSITION';

END_TRANSITION : 'END_TRANSITION';

PRIORITY : 'PRIORITY';

FROM : 'FROM';

ACTION : 'ACTION';

END_ACTION : 'END_ACTION';

// Configuration and resource declaration

CONFIGURATION : 'CONFIGURATION';

END_CONFIGURATION : 'END_CONFIGURATION';

RESOURCE : 'RESOURCE';

ON : 'ON';

END_RESOURCE : 'END_RESOURCE';

Access_Direction : 'READ_WRITE' | 'READ_ONLY';

TASK : 'TASK';

INTERVAL : 'INTERVAL';

SINGLE : 'SINGLE';

WITH : 'WITH';

VAR_CONFIG : 'VAR_CONFIG';

//Namespace
NAMESPACE : 'NAMESPACE';

INTERNAL : 'INTERNAL';

END_NAMESPACE : 'END_NAMESPACE';

USING : 'USING';

//Instruction List (IL)
//pass

// Language Structured Text (ST)
OR : 'OR';

XOR : 'XOR';

AND : 'AND';

MOD : 'MOD';

NOT : 'NOT';

Multibit_Part_Access : Dot ( Unsigned_Int | '%' ( 'X' | 'B' | 'W' | 'D' | 'L' ) ? Unsigned_Int );

SUPER : 'SUPER';

RETURN : 'RETURN';

IF : 'IF';

THEN : 'THEN';

ELSIF : 'ELSIF';

ELSE : 'ELSE';

END_IF : 'END_IF';

CASE : 'CASE';

END_CASE : 'END_CASE';

EXIT : 'EXIT';

CONTINUE : 'CONTINUE';

FOR : 'FOR';

DO : 'DO';

END_FOR : 'END_FOR';

TO : 'TO';

BY : 'BY';

WHILE : 'WHILE';

END_WHILE : 'END_WHILE';

REPEAT : 'REPEAT';

UNTIL : 'UNTIL';

END_REPEAT : 'END_REPEAT';

Identifier : Letter (Letter|Digit)*;

//Comments and white spaces
Whitespace: [ \t]+ -> skip;

Newline: ('\r' '\n'? | '\n') -> skip;

BlockComment: '/*' .*? '*/' -> skip;

LineComment: '//' ~ [\r\n]* -> skip;

//signs
Dot : '.';
Semi : ';';
Colon : ':';
Assign : ':=';
LeftParen: '(';
RightParen: ')';
RangeDot : '..';
Caret: '^';
Comma: ',';
Underline: '_';
TypeSign : '#';
LeftBracket: '[';
RightBracket: ']';
StarStar : '**';
AndSign : '&';
Equal : '=';
NotEqual : '<>';
Less: '<';
Greater: '>';
LessEqual: '<=';
GreaterEqual: '>=';
Plus: '+';
Minus: '-';
Div: '/';
QuestionEqual : '?=';
LeftAssign : '=>';
Star: '*';